<!doctype html>
<html lang="en-US">

<head>
  <title>Part grouping: status</title>
  <link href="/assets/index.css" rel="stylesheet" type="text/css" />
  <script type="importmap">
      {
        "imports": {
          "react": "https://esm.sh/react@18.3.1",
          "react-dom": "https://esm.sh/react-dom@18.3.1",
          "react-dom/": "https://esm.sh/react-dom@18.3.1/",
          "@testduet/wait-for": "https://unpkg.com/@testduet/wait-for@main/dist/wait-for.mjs",
          "@fluentui/react-components": "https://esm.sh/@fluentui/react-components?deps=react@18.3.1&exports=FluentProvider,createDarkTheme,webLightTheme"
        }
      }
    </script>
  <script crossorigin="anonymous" src="/test-harness.js"></script>
  <script crossorigin="anonymous" src="/test-page-object.js"></script>
  <script type="module">
    import React from 'react';
    window.React = React;
  </script>
  <script defer crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
  <script defer crossorigin="anonymous" src="/__dist__/botframework-webchat-fluent-theme.development.js"></script>
  <style type="text/css">
    #webchat {
      width: 640px;
    }

    .fui-FluentProvider {
      height: 100%;
    }

    .theme.variant-copilot-deprecated {
      --webchat__color--surface: var(--colorGrey98);
    }
  </style>
</head>

<body>
  <main id="webchat"></main>
  <script type="module">
    import React from 'react';
    import { createRoot } from 'react-dom/client';
    import { FluentProvider, createDarkTheme, webLightTheme } from '@fluentui/react-components';
    import { waitFor } from '@testduet/wait-for';

    run(async function () {
      const {
        WebChat: { FluentThemeProvider, ReactWebChat }
      } = window;

      const { directLine, store } = testHelpers.createDirectLineEmulator();

      const searchParams = new URLSearchParams(location.search);
      const variant = searchParams.get('variant');
      const theme = searchParams.get('fluent-theme');

      await host.windowSize(640, 1024, document.getElementById('webchat'));
      await host.sendDevToolsCommand('Emulation.setEmulatedMedia', {
        features: [
          { name: 'prefers-reduced-motion', value: 'reduce' },
          ...(theme === 'dark' || theme === 'light'
            ? [{ name: 'prefers-color-scheme', value: theme }]
            : [])
        ]
      });

      const root = createRoot(document.getElementById('webchat'));

      let fluentTheme;
      let codeBlockTheme;

      if (theme === 'dark' || window.matchMedia('(prefers-color-scheme: dark)').matches && theme !== 'light') {
        fluentTheme = {
          ...createDarkTheme({
            10: '#12174c',
            20: '#1a1f5b',
            30: '#21276a',
            40: '#293079',
            50: '#303788',
            60: '#384097',
            70: '#4049a7',
            80: '#151e80',
            90: '#4f59c5',
            100: '#5661d4',
            110: '#5e69e3',
            120: '#7982e8',
            130: '#949bec',
            140: '#afb5f1',
            150: '#c9cdf6',
            160: '#e4e6fa'
          }),
          colorNeutralBackground1Disabled: '#101010',
          colorNeutralBackground1Hover: '#101010',
          colorNeutralForeground5: '#424242',
          colorGrey98: '#1b1b1b'
        };
        codeBlockTheme = 'github-dark-default';
      } else {
        fluentTheme = {
          ...webLightTheme,
          colorNeutralForeground1: '#1b1b1b',
          colorGrey98: '#fafafa'
        };
        codeBlockTheme = 'github-light-default';
      }

      if (variant) {
        window.checkAccessibility = async () => { }
      }

      const webChatProps = { directLine, store, styleOptions: { codeBlockTheme } };

      root.render(
        variant ?
          React.createElement(
            FluentProvider,
            { className: 'fui-FluentProvider', theme: fluentTheme },
            React.createElement(
              FluentThemeProvider,
              { variant: variant },
              React.createElement(ReactWebChat, webChatProps)
            )
          ) :
          React.createElement(ReactWebChat, webChatProps)
      );

      await pageConditions.uiConnected();

      const botIcon = '';

      const aiMessageEntity = {
        '@context': 'https://schema.org',
        '@id': '',
        '@type': 'Message',
        keywords: ['AIGeneratedContent', 'AnalysisMessage'],
        type: 'https://schema.org/Message',
        author: {
          '@context': 'https://schema.org',
          '@type': 'Person',
          image: botIcon,
          name: 'Research',
        },
        isPartOf: {
          '@id': '_:h-00001',
          '@type': 'HowTo',
        }
      };

      const withModifiers = (activity, { position, status, abstract }) => ({
        ...activity,
        entities: activity.entities.map(entity => ({
          ...entity,
          ...(typeof abstract !== 'undefined' ? { abstract } : {}),
          ...(typeof position !== 'undefined' ? { position } : {}),
          creativeWorkStatus: status
        }))
      });

      directLine.emulateIncomingActivity({
        from: { role: 'user' },
        type: 'message',
        text: `Message from user.`
      });

      const activities = [
        { entities: [{ ...aiMessageEntity }], id: 'a-00001' },
        { entities: [{ ...aiMessageEntity }], id: 'a-00002' },
        { entities: [{ ...aiMessageEntity }], id: 'a-00003' },
        { entities: [{ ...aiMessageEntity }], id: 'a-00004' },
        { entities: [{ ...aiMessageEntity }], id: 'a-00005' },
      ];

      // Test Case 1: Initial activities with different statuses
      // When: adding activities with various statuses
      directLine.emulateIncomingActivity(withModifiers(activities.at(0), { position: 1, status: 'Incomplete', abstract: 'one' }));
      directLine.emulateIncomingActivity(withModifiers(activities.at(1), { position: 2, status: 'Published', abstract: 'two' }));
      directLine.emulateIncomingActivity(withModifiers(activities.at(2), { position: 3, status: undefined, abstract: 'three' }));

      // Then: show activities with corresponding status indicators
      await pageConditions.numActivitiesShown(4);
      await host.snapshot('local');

      // Test Case 2: Multiple activities being worked on
      // When: setting another activity to 'Incomplete'
      directLine.emulateIncomingActivity(withModifiers(activities.at(2), { status: 'Incomplete', abstract: 'three in progress' }));

      // Then: show multiple loading indicators
      await pageConditions.numActivitiesShown(4);
      await host.snapshot('local');

      // Test Case 3: Pause and continue work
      // When: pausing work on the first activity
      directLine.emulateIncomingActivity(withModifiers(activities.at(0), { status: undefined, abstract: 'one paused' }));

      // Then: show the first activity with an unset status indicator
      await pageConditions.numActivitiesShown(4);
      await host.snapshot('local');

      // When: continuing work on the first activity
      directLine.emulateIncomingActivity(withModifiers(activities.at(0), { status: 'Incomplete', abstract: 'one resumed' }));

      // Then: show the loading indicator again for the first activity
      await pageConditions.numActivitiesShown(4);
      await host.snapshot('local');

      // Test Case 4: Complete all work
      // When: marking all activities as 'Published'
      directLine.emulateIncomingActivity(withModifiers(activities.at(0), { status: 'Published', abstract: 'one done' }));
      directLine.emulateIncomingActivity(withModifiers(activities.at(2), { status: 'Published', abstract: 'three done' }));

      // Then: all activities should show the 'Published' status indicator
      await pageConditions.numActivitiesShown(4);
      await host.snapshot('local');

      // Test Case 5: Update position and start work
      // When: adding new activities and then updating one to start work
      directLine.emulateIncomingActivity(withModifiers(activities.at(3), { position: 4, status: undefined, abstract: 'four' }));
      directLine.emulateIncomingActivity(withModifiers(activities.at(4), { position: 5, status: undefined, abstract: 'five' }));
      await pageConditions.numActivitiesShown(6);
      await host.snapshot('local');

      // Become 1-5-2-3-4.
      directLine.emulateIncomingActivity(withModifiers(activities.at(4), { position: 1, status: 'Incomplete', abstract: 'five moved to one and in progress' }));

      // Then: show the activity moved to the new position with a loading indicator
      await pageConditions.numActivitiesShown(6);
      await host.snapshot('local');

      // Test Case 6: Start work on an item, then another item is inserted before it
      // When: starting work on an item and then inserting another before it
      directLine.emulateIncomingActivity(withModifiers(activities.at(3), { status: 'Incomplete', abstract: 'four in progress' }));
      await host.snapshot('local');

      // Become 5-2-3-4-1.
      directLine.emulateIncomingActivity(withModifiers(activities.at(0), { position: 3, status: 'Incomplete', abstract: 'one (was done) moved to three and in progress' }));

      // Then: show the new item inserted with a loading indicator, and the other items shifted
      await pageConditions.numActivitiesShown(6);
      await host.snapshot('local');

      // Test Case 7: Complete all remaining work
      // When: marking all incomplete activities as 'Published'
      directLine.emulateIncomingActivity(withModifiers(activities.at(4), { status: 'Published', abstract: 'five done' }));
      directLine.emulateIncomingActivity(withModifiers(activities.at(0), { status: 'Published', abstract: 'one done again' }));
      directLine.emulateIncomingActivity(withModifiers(activities.at(3), { status: 'Published', abstract: 'four done' }));

      // Then: all activities should show the 'Published' status indicator
      await pageConditions.numActivitiesShown(6);
      await host.snapshot('local');
    });
  </script>
</body>

</html>
